diff --git a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,25 +1,10 @@
-cmake_minimum_required(VERSION 2.8)
-project(METIS)
+cmake_minimum_required(VERSION 3.0)
+project(METIS VERSION 5.1.0 LANGUAGES C)
 
-set(GKLIB_PATH "GKlib" CACHE PATH "path to GKlib")
-set(SHARED FALSE CACHE BOOL "build a shared library")
-
-if(MSVC)
-  set(METIS_INSTALL FALSE)
-else()
-  set(METIS_INSTALL TRUE)
-endif()
-
-# Configure libmetis library.
-if(SHARED)
-  set(METIS_LIBRARY_TYPE SHARED)
-else()
-  set(METIS_LIBRARY_TYPE STATIC)
-endif(SHARED)
-
-include(${GKLIB_PATH}/GKlibSystem.cmake)
+include(GNUInstallDirs)
+include(GKlib/GKlibSystem.cmake)
 # Add include directories.
-include_directories(${GKLIB_PATH})
+include_directories(GKlib)
 include_directories(include)
 # Recursively look for CMakeLists.txt in subdirs.
 add_subdirectory("include")
diff --git a/GKlib/CMakeLists.txt b/GKlib/CMakeLists.txt
--- a/GKlib/CMakeLists.txt
+++ b/GKlib/CMakeLists.txt
@@ -1,21 +1,23 @@
-cmake_minimum_required(VERSION 2.8)
-project(GKlib)
+cmake_minimum_required(VERSION 3.0)
+project(GKlib LANGUAGES C)
 
-get_filename_component(abs "." ABSOLUTE)
-set(GKLIB_PATH ${abs})
-unset(abs)
+include(GNUInstallDirs)
 include(GKlibSystem.cmake)
 
 include_directories(".")
-add_library(GKlib STATIC ${GKlib_sources})
+add_library(GKlib ${GKlib_sources})
+if(OPENMP AND OPENMP_FOUND)
+  set_property(TARGET GKlib APPEND PROPERTY COMPILE_FLAGS ${OpenMP_C_FLAGS})
+  set_property(TARGET GKlib APPEND PROPERTY LINK_FLAGS ${OpenMP_C_FLAGS})
+endif()
 if(UNIX)
-  target_link_libraries(GKlib m)
+  target_link_libraries(GKlib PRIVATE m)
 endif(UNIX)
 
 include_directories("test")
 add_subdirectory("test")
 
 install(TARGETS GKlib
-  ARCHIVE DESTINATION lib
-  LIBRARY DESTINATION lib)
-install(FILES ${GKlib_includes} DESTINATION include)
+  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
+install(FILES ${GKlib_includes} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/GKlib)
diff --git a/GKlib/GKlibSystem.cmake b/GKlib/GKlibSystem.cmake
--- a/GKlib/GKlibSystem.cmake
+++ b/GKlib/GKlibSystem.cmake
@@ -15,35 +15,28 @@
 
 # Add compiler flags.
 if(MSVC)
-  set(GKlib_COPTS "/Ox")
-  set(GKlib_COPTIONS "-DWIN32 -DMSC -D_CRT_SECURE_NO_DEPRECATE -DUSE_GKREGEX")
-elseif(MINGW)
-  set(GKlib_COPTS "-DUSE_GKREGEX")
-else()
-  set(GKlib_COPTS "-O3")
-  set(GKlib_COPTIONS "-DLINUX -D_FILE_OFFSET_BITS=64")
-endif(MSVC)
-if(CYGWIN)
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -DCYGWIN")
-endif(CYGWIN)
+  add_definitions(-DWIN32 -DMSC -D_CRT_SECURE_NO_DEPRECATE)
+elseif(UNIX)
+  add_definitions(-DLINUX -D_FILE_OFFSET_BITS=64)
+elseif(CYGWIN)
+  add_definitions(-DCYGWIN)
+endif()
+
 if(CMAKE_COMPILER_IS_GNUCC)
 # GCC opts.
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -std=c99 -fno-strict-aliasing")
-  if(NOT MINGW)
-      set(GKlib_COPTIONS "${GKlib_COPTIONS} -fPIC")
-  endif(NOT MINGW)
+  add_compile_options(-std=c99 -fno-strict-aliasing)
 # GCC warnings.
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -Wall -pedantic -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unknown-pragmas")
+  add_compile_options(-Wall -pedantic -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unknown-pragmas)
 elseif(${CMAKE_C_COMPILER_ID} MATCHES "Sun")
 # Sun insists on -xc99.
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -xc99")
+  add_compile_options(-xc99)
 endif(CMAKE_COMPILER_IS_GNUCC)
 
 # Find OpenMP if it is requested.
 if(OPENMP)
   include(FindOpenMP)
   if(OPENMP_FOUND)
-    set(GKlib_COPTIONS "${GKlib_COPTIONS} -D__OPENMP__ ${OpenMP_C_FLAGS}")
+    add_definitions(-D__OPENMP__)
   else()
     message(WARNING "OpenMP was requested but support was not found")
   endif(OPENMP_FOUND)
@@ -52,64 +45,64 @@
 
 # Add various definitions.
 if(GDB)
-  set(GKlib_COPTS "${GKlib_COPTS} -g")
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -Werror")
+  add_compile_options(-g)
+  add_compile_options(-Werror)
 endif(GDB)
 
 
 if(DEBUG)
-  set(GKlib_COPTS "-g")
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -DDEBUG")
+  add_compile_options(-g)
+  add_definitions(-DDEBUG)
 endif(DEBUG)
 
 if(GPROF)
-  set(GKlib_COPTS "-pg")
+  add_compile_options(-pg)
 endif(GPROF)
 
 if(NOT ASSERT)
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -DNDEBUG")
+  add_definitions(-DNDEBUG)
 endif(NOT ASSERT)
 
 if(NOT ASSERT2)
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -DNDEBUG2")
+  add_definitions(-DNDEBUG2)
 endif(NOT ASSERT2)
 
 
 # Add various options
 if(PCRE)
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -D__WITHPCRE__")
+  add_definitions(-D__WITHPCRE__)
 endif(PCRE)
 
 if(GKREGEX)
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -DUSE_GKREGEX")
+  add_definitions(-DUSE_GKREGEX)
 endif(GKREGEX)
 
 if(GKRAND)
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -DUSE_GKRAND")
+  add_definitions(-DUSE_GKRAND)
 endif(GKRAND)
 
 
 # Check for features.
 check_include_file(execinfo.h HAVE_EXECINFO_H)
 if(HAVE_EXECINFO_H)
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -DHAVE_EXECINFO_H")
+  add_definitions(-DHAVE_EXECINFO_H)
 endif(HAVE_EXECINFO_H)
 
 check_function_exists(getline HAVE_GETLINE)
 if(HAVE_GETLINE)
-  set(GKlib_COPTIONS "${GKlib_COPTIONS} -DHAVE_GETLINE")
+  add_definitions(-DHAVE_GETLINE)
 endif(HAVE_GETLINE)
 
 
 # Custom check for TLS.
 if(MSVC)
-   set(GKlib_COPTIONS "${GKlib_COPTIONS} -D__thread=__declspec(thread)")
+   add_definitions(-D__thread=__declspec\(thread\))
 else()
   # This if checks if that value is cached or not.
   if("${HAVE_THREADLOCALSTORAGE}" MATCHES "^${HAVE_THREADLOCALSTORAGE}$")
     try_compile(HAVE_THREADLOCALSTORAGE
       ${CMAKE_BINARY_DIR}
-      ${GKLIB_PATH}/conf/check_thread_storage.c)
+      ${CMAKE_CURRENT_LIST_DIR}/conf/check_thread_storage.c)
     if(HAVE_THREADLOCALSTORAGE)
       message(STATUS "checking for thread-local storage - found")
     else()
@@ -117,13 +110,10 @@
     endif()
   endif()
   if(NOT HAVE_THREADLOCALSTORAGE)
-    set(GKlib_COPTIONS "${GKlib_COPTIONS} -D__thread=")
+    add_definitions(-D__thread=)
   endif()
 endif()
 
-# Finally set the official C flags.
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GKlib_COPTIONS} ${GKlib_COPTS}")
-
 # Find GKlib sources.
-file(GLOB GKlib_sources ${GKLIB_PATH}/*.c)
-file(GLOB GKlib_includes ${GKLIB_PATH}/*.h)
+file(GLOB GKlib_sources ${CMAKE_CURRENT_LIST_DIR}/*.c)
+file(GLOB GKlib_includes ${CMAKE_CURRENT_LIST_DIR}/*.h)
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,6 @@
 gprof      = not-set
 openmp     = not-set
 prefix     = not-set
-gklib_path = not-set
 shared     = not-set
 cc         = not-set
 
@@ -20,10 +19,6 @@
 
 # Process configuration options.
 CONFIG_FLAGS = -DCMAKE_VERBOSE_MAKEFILE=1
-ifeq ($(gklib_path), not-set)
-    gklib_path = GKlib
-endif
-CONFIG_FLAGS += -DGKLIB_PATH=$(abspath $(gklib_path))
 ifneq ($(gdb), not-set)
     CONFIG_FLAGS += -DGDB=$(gdb)
 endif
@@ -46,7 +41,7 @@
     CONFIG_FLAGS += -DCMAKE_INSTALL_PREFIX=$(prefix)
 endif
 ifneq ($(shared), not-set)
-    CONFIG_FLAGS += -DSHARED=1
+    CONFIG_FLAGS += -DBUILD_SHARED_LIBS=1
 endif
 ifneq ($(cc), not-set)
     CONFIG_FLAGS += -DCMAKE_C_COMPILER=$(cc)
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -1,3 +1 @@
-if(METIS_INSTALL)
-  install(FILES metis.h DESTINATION include)
-endif()
+install(FILES metis.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/metis)
diff --git a/libmetis/CMakeLists.txt b/libmetis/CMakeLists.txt
--- a/libmetis/CMakeLists.txt
+++ b/libmetis/CMakeLists.txt
@@ -3,14 +3,20 @@
 # Find sources.
 file(GLOB metis_sources *.c)
 # Build libmetis.
-add_library(metis ${METIS_LIBRARY_TYPE} ${GKlib_sources} ${metis_sources})
+add_library(metis ${GKlib_sources} ${metis_sources})
+if(OPENMP AND OPENMP_FOUND)
+  set_property(TARGET metis APPEND PROPERTY COMPILE_FLAGS ${OpenMP_C_FLAGS})
+  set_property(TARGET metis APPEND PROPERTY LINK_FLAGS ${OpenMP_C_FLAGS})
+endif()
 if(UNIX)
-  target_link_libraries(metis m)
+  target_link_libraries(metis PRIVATE m)
 endif()
 
-if(METIS_INSTALL)
-  install(TARGETS metis
-    LIBRARY DESTINATION lib
-    RUNTIME DESTINATION lib
-    ARCHIVE DESTINATION lib)
-endif()
+install(TARGETS metis
+  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+configure_file(metis.pc.in metis.pc @ONLY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/metis.pc
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
diff --git a/libmetis/metis.pc.in b/libmetis/metis.pc.in
new file mode 100644
--- /dev/null
+++ b/libmetis/metis.pc.in
@@ -0,0 +1,12 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
+
+Name: @PROJECT_NAME@
+Description: Software for partitioning unstructured graphs and meshes
+Version: @PROJECT_VERSION@
+URL: http://glaros.dtc.umn.edu/gkhome/metis/metis/overview
+Libs: -L${libdir} -lmetis
+Libs.private: -lm
+Cflags: -I${includedir}/metis
diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt
--- a/programs/CMakeLists.txt
+++ b/programs/CMakeLists.txt
@@ -1,6 +1,5 @@
 # These programs use internal metis data structures.
 include_directories(../libmetis)
-link_directories(/home/karypis/local/lib)
 # Build program.
 add_executable(gpmetis gpmetis.c cmdline_gpmetis.c io.c stat.c)
 add_executable(ndmetis ndmetis.c cmdline_ndmetis.c io.c smbfactor.c)
@@ -13,10 +12,8 @@
 #  target_link_libraries(${prog} metis profiler)
 endforeach(prog)
 
-if(METIS_INSTALL)
-  install(TARGETS gpmetis ndmetis mpmetis m2gmetis graphchk cmpfillin
-    RUNTIME DESTINATION bin)
-endif()
+install(TARGETS gpmetis ndmetis mpmetis m2gmetis graphchk cmpfillin
+  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Try to find subversion revision.
 set(SVNREV "")
